package com.yin.waimai.service;

import com.yin.waimai.dto.CreateOrderRequestDTO;
import com.yin.waimai.dto.OrderDTO;
import com.yin.waimai.enums.OrderStatus;
import com.yin.waimai.model.LogisticsTrace;
import com.yin.waimai.model.Order;

import java.util.List;
import java.util.Optional;

public interface OrderService {

    /**
     * 创建新订单。
     * @param requestDTO 包含订单创建信息的DTO
     * @param username 创建订单的用户名
     * @return 创建成功后的订单DTO
     */
    OrderDTO createOrder(CreateOrderRequestDTO requestDTO, String username);

    /**
     * 根据订单号查询订单详情。
     * @param orderNumber 订单号
     * @return 订单DTO，如果未找到则返回null
     */
    OrderDTO getOrderByOrderNumber(String orderNumber);

    /**
     * 根据订单号查询订单实体（主要供内部或需要完整实体的场景使用）。
     * Controller 中 getOrderByNumber/getOrderTraces/getOrderPath 用于判断订单是否存在时会调用此方法。
     * @param orderNumber 订单号
     * @return Optional包含Order对象，如果未找到则为空
     */
    Optional<Order> findOrderEntityByNumber(String orderNumber);

    /**
     * 更新订单状态并记录物流轨迹。
     * @param orderNumber 订单号
     * @param newStatus   新的订单状态枚举
     * @param operator    操作员标识
     * @param location    操作发生地点
     * @param description 操作描述
     * @return 更新后的订单DTO
     */
    OrderDTO updateOrderStatusAndAddTrace(String orderNumber, OrderStatus newStatus, String operator, String location, String description);

    /**
     * 根据订单号查询该订单的所有物流轨迹。
     * @param orderNumber 订单号
     * @return 物流轨迹列表
     */
    List<LogisticsTrace> getLogisticsTracesByOrderNumber(String orderNumber);

    /**
     * 获取订单的配送路径点
     * @param orderNumber 订单号
     * @return 路径坐标点列表 [[经度,纬度], [经度,纬度], ...]，如果成功；否则为 null 或空列表
     */
    List<List<Double>> getOrderRouteCoordinates(String orderNumber);
    
    /**
     * 将订单分配给配送员
     * @param orderNumber 订单号
     * @param deliveryPersonId 配送员ID
     * @param operator 操作员
     * @return 更新后的订单DTO
     */
    OrderDTO acceptOrder(String orderNumber, String deliveryPersonId, String operator);
    
    /**
     * 手动将订单分配给配送员
     * @param orderNumber 订单号
     * @param deliveryPersonId 配送员ID
     * @param operator 操作员
     * @return 更新后的订单DTO
     */
    OrderDTO assignDeliveryPerson(String orderNumber, String deliveryPersonId, String operator);
    
    /**
     * 自动为订单分配最近的空闲配送员
     * @param orderNumber 订单号
     * @param operator 操作员
     * @return 更新后的订单DTO，如果没有可用的配送员则返回未分配状态的订单
     */
    OrderDTO autoAssignDeliveryPerson(String orderNumber, String operator);
    
    /**
     * 根据配送员ID查询订单列表
     * @param deliveryPersonId 配送员ID
     * @return 订单DTO列表
     */
    List<OrderDTO> getOrdersByDeliveryPersonId(String deliveryPersonId);
    
    /**
     * 获取可接单的订单列表（状态为PENDING_COLLECTION且未分配配送员）
     * @return 可接单的订单列表
     */
    List<OrderDTO> getAvailableOrders();
    
    /**
     * 根据订单号删除订单
     * @param orderNumber 订单号
     * @return 删除的记录数
     */
    long deleteByOrderNumber(String orderNumber);

    /**
     * 获取最近的订单
     * @param limit 限制数量
     * @return 订单DTO列表
     */
    List<OrderDTO> getRecentOrders(int limit);

    /**
     * 获取所有订单
     * @return 订单DTO列表
     */
    List<OrderDTO> findAllOrders();

    /**
     * 获取订单总数
     * @return 订单总数
     */
    long countOrders();

    /**
     * 获取已完成订单数量
     * @return 已完成订单数量
     */
    long countCompletedOrders();
}